home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994…tember: Reference Library / Dev.CD Sep 94.toast / Periodicals / develop / develop Issue 6 / develop 6 code / TCP / NewsWatcher / NewsWatcher 2.0d15 source / source / prefsdlog.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-08-30  |  24.8 KB  |  966 lines  |  [TEXT/KAHL]

  1. /*----------------------------------------------------------------------------
  2.  
  3.     prefsdlog.c
  4.  
  5.     This module handles the preferences dialog.
  6.     
  7.     Portions copyright © 1990, Apple Computer.
  8.     Portions copyright © 1993, Northwestern University.
  9.  
  10. ----------------------------------------------------------------------------*/
  11.  
  12. #include <stdio.h>
  13. #include <string.h>
  14. #include <Packages.h>
  15.  
  16. #include "glob.h"
  17. #include "prefsdlog.h"
  18. #include "dlgutil.h"
  19. #include "util.h"
  20. #include "popup.h"
  21. #include "font.h"
  22. #include "sfutil.h"
  23. #include "log.h"
  24.  
  25.  
  26.  
  27. /* Items common to all topics. The kInit and kTerm items are pseudo-items
  28.    used to intialize and terminate the topics. The OK and Cancel buttons
  29.    are also common to all topics (item numbers 1 and 2). */
  30.  
  31. #define kTopicPopup            3
  32. #define kInit                100
  33. #define kTerm                101
  34.  
  35. #define kPrefsDlg            300
  36. #define kGeneralOptions        1
  37. #define kServerAddresses    2
  38. #define kServerOptions        3
  39. #define kPersonalInfo        4
  40. #define kSignature            5
  41. #define kRemoteHost            6
  42. #define kFontSize            7
  43. #define kSavedText            8
  44. #define kAuthorization        9
  45.  
  46. /* General options topic. */
  47.  
  48. #define kShowAuthors        4
  49. #define kShowHeaders        5
  50. #define kCollapseThreads    6
  51. #define kKeypadShortcuts    7
  52. #define kShowKilled            8
  53. #define kCopyReplies        9
  54. #define kCheckNewGroups        10
  55. #define kAreYouSure            11
  56. #define kLogActionsToFile    12
  57. #define kExpandHilited        13
  58. #define kMaxArticles        15
  59.  
  60. /* Server info topic. */
  61.  
  62. #define kNewsServer            6
  63. #define kMailServer            8
  64.  
  65. /* Server options topic. */
  66.  
  67. #define kBatchedGroupCmds    5
  68. #define kUseXPAT            6
  69. #define kNoNewConnection    7
  70. #define kNoModeReader        8
  71.  
  72. /* Personal info topic. */
  73.  
  74. #define kFullName            6
  75. #define kOrganization        8
  76. #define kMailAddress        10
  77.  
  78. /* Signature topic. */
  79.  
  80. #define kSigStaticText        4
  81. #define kSignature            5
  82. #define kAddSigSeparator    6
  83.  
  84. /* Remote host info topic. */
  85.  
  86. #define    kRemoteHost            6
  87. #define    kRemoteLogin        8
  88. #define    kRemotePassword        10
  89. #define kRemotePath            12
  90. #define kAutoGetPut            13
  91. #define    kSavePassword        14
  92.  
  93. /* Font/size topic. */
  94.  
  95. #define kListFontPopup         5
  96. #define kListSizeBox        7
  97. #define kListSizePopup        8
  98. #define kListSample            9
  99. #define kListVertLine        10
  100. #define kTextFontPopup        12
  101. #define kTextSizeBox        14
  102. #define kTextSizePopup        15
  103. #define kTextSample            16
  104.  
  105. /* Saved text file topic. */
  106.  
  107. #define kAppBorder            5
  108. #define kAppName            6
  109. #define kAppButton            7
  110. #define kDirCheckBox        8
  111. #define kDirBorder            9
  112. #define kDirName            10
  113. #define kDirButton            11
  114.  
  115. /* Authoriation topic. */
  116.  
  117.  
  118.  
  119.  
  120. static Str255 gStaticText;        /* static text for signature dialog */
  121.  
  122. static short gListFontID;        /* current list font id */
  123. static short gListFontSize;        /* current list font size */
  124. static short gTextFontID;        /* current text font id */
  125. static short gTextFontSize;        /* current text font size */
  126.  
  127.  
  128.  
  129. /*----------------------------------------------------------------------------
  130.     GeneralOptions
  131.  
  132.     Handles the general options preferences dialog.
  133.     
  134.     Entry:    prefs = pointer to new prefs.
  135.             dlg = pointer to dialog.
  136.             item = item number hit.
  137. ----------------------------------------------------------------------------*/
  138.  
  139. static void GeneralOptions (TPrefRec *prefs, DialogPtr dlg, short item)
  140. {
  141.     switch (item) {
  142.     
  143.         case kInit:
  144.         
  145.             DlgSetCheck(dlg, kShowAuthors, prefs->showAuthors);
  146.             DlgSetCheck(dlg, kShowHeaders, prefs->showHeaders);
  147.             DlgSetCheck(dlg, kCollapseThreads, prefs->showThreadsCollapsed);
  148.             DlgSetCheck(dlg, kKeypadShortcuts, prefs->keypadShortcuts);
  149.             DlgSetCheck(dlg, kShowKilled, prefs->showKilledArticles);
  150.             DlgSetCheck(dlg, kCopyReplies, prefs->replyCC);
  151.             DlgSetCheck(dlg, kCheckNewGroups, prefs->checkForNewGroups);
  152.             DlgSetCheck(dlg, kAreYouSure, prefs->areYouSureAlert);
  153.             DlgSetCheck(dlg, kLogActionsToFile, prefs->logActionsToFile);
  154.             DlgSetCheck(dlg, kExpandHilited, prefs->expandHilited);
  155.             DlgSetNumber(dlg, kMaxArticles, prefs->maxFetch);
  156.             SetItemNumeric(dlg, kMaxArticles, true);
  157.             SetItemMaxLength(dlg, kMaxArticles, 6);
  158.             SelIText(dlg, kMaxArticles, 0, 0x7fff);
  159.             #ifndef FILTERS
  160.                 DlgSetCheck(dlg, kShowKilled, false);
  161.                 DlgSetCheck(dlg, kExpandHilited, false);
  162.                 DlgEnableItem (dlg, kShowKilled, false);
  163.                 DlgEnableItem (dlg, kExpandHilited, false);
  164.             #endif
  165.             break;
  166.             
  167.         case kTerm:
  168.             
  169.             prefs->showAuthors = DlgGetCheck(dlg, kShowAuthors);
  170.             prefs->showHeaders = DlgGetCheck(dlg, kShowHeaders);
  171.             prefs->showThreadsCollapsed = DlgGetCheck(dlg, kCollapseThreads);
  172.             prefs->keypadShortcuts = DlgGetCheck(dlg, kKeypadShortcuts);
  173.             prefs->showKilledArticles = DlgGetCheck(dlg, kShowKilled);
  174.             prefs->replyCC = DlgGetCheck(dlg, kCopyReplies);
  175.             prefs->checkForNewGroups = DlgGetCheck(dlg, kCheckNewGroups);
  176.             prefs->areYouSureAlert = DlgGetCheck(dlg, kAreYouSure);
  177.             prefs->logActionsToFile = DlgGetCheck(dlg, kLogActionsToFile);
  178.             prefs->expandHilited = DlgGetCheck(dlg, kExpandHilited);
  179.             prefs->maxFetch = DlgGetNumber(dlg, kMaxArticles);
  180.             break;
  181.             
  182.         case kShowAuthors:
  183.         case kShowHeaders:
  184.         case kCollapseThreads:
  185.         case kKeypadShortcuts:
  186.         case kShowKilled:
  187.         case kCopyReplies:
  188.         case kCheckNewGroups:
  189.         case kAreYouSure:
  190.         case kLogActionsToFile:
  191.         case kExpandHilited:
  192.         
  193.             DlgToggleCheck(dlg, item);
  194.             break;
  195.             
  196.     }
  197. }
  198.  
  199.  
  200.  
  201. /*----------------------------------------------------------------------------
  202.     Server
  203.  
  204.     Handles the server info preferences dialog.
  205.     
  206.     Entry:    prefs = pointer to new prefs.
  207.             dlg = pointer to dialog.
  208.             item = item number hit.
  209. ----------------------------------------------------------------------------*/
  210.  
  211. static void Server (TPrefRec *prefs, DialogPtr dlg, short item)
  212. {
  213.     Boolean enable;
  214.  
  215.     switch (item) {
  216.     
  217.         case kInit:
  218.         
  219.             DlgSetPString(dlg, kNewsServer, prefs->newsServerName);
  220.             SetItemMaxLength(dlg, kNewsServer, 255);
  221.             DlgSetPString(dlg, kMailServer, prefs->mailServerName);
  222.             SetItemMaxLength(dlg, kMailServer, 255);
  223.             if (*prefs->newsServerName == 0) {
  224.                 SelIText(dlg, kNewsServer, 0, 0);
  225.             } else if (*prefs->mailServerName == 0) {
  226.                 SelIText(dlg, kMailServer, 0, 0);
  227.             } else {
  228.                 SelIText(dlg, kNewsServer, 0, 0x7fff);
  229.             }
  230.             break;
  231.             
  232.         case kTerm:
  233.             
  234.             break;
  235.             
  236.         case kNewsServer:
  237.         case kMailServer:
  238.         
  239.             DlgGetPString(dlg, kNewsServer, prefs->newsServerName);
  240.             DlgGetPString(dlg, kMailServer, prefs->mailServerName);
  241.             enable = *prefs->newsServerName != 0 && *prefs->mailServerName != 0;
  242.             DlgEnableItem(dlg, ok, enable);
  243.             DlgEnableItem(dlg, kTopicPopup, enable);
  244.             
  245.     }
  246. }
  247.  
  248.  
  249.  
  250. /*----------------------------------------------------------------------------
  251.     ServerOptions
  252.  
  253.     Handles the server options preferences dialog.
  254.     
  255.     Entry:    prefs = pointer to new prefs.
  256.             dlg = pointer to dialog.
  257.             item = item number hit.
  258. ----------------------------------------------------------------------------*/
  259.  
  260. static void ServerOptions (TPrefRec *prefs, DialogPtr dlg, short item)
  261. {
  262.     switch (item) {
  263.     
  264.         case kInit:
  265.         
  266.             DlgSetCheck(dlg, kBatchedGroupCmds, prefs->batchedGroupCmds);
  267.             DlgSetCheck(dlg, kUseXPAT, prefs->useXPAT);
  268.             DlgSetCheck(dlg, kNoNewConnection, prefs->noNewConnection);
  269.             DlgSetCheck(dlg, kNoModeReader, prefs->noModeReader);
  270.             break;
  271.             
  272.         case kTerm:
  273.             
  274.             prefs->batchedGroupCmds = DlgGetCheck(dlg, kBatchedGroupCmds);
  275.             prefs->useXPAT = DlgGetCheck(dlg, kUseXPAT);
  276.             prefs->noNewConnection = DlgGetCheck(dlg, kNoNewConnection);
  277.             prefs->noModeReader = DlgGetCheck(dlg, kNoModeReader);
  278.             break;
  279.             
  280.         case kBatchedGroupCmds:
  281.         case kUseXPAT:
  282.         case kNoNewConnection:
  283.         case kNoModeReader:
  284.         
  285.             DlgToggleCheck(dlg, item);
  286.             break;
  287.             
  288.     }
  289. }
  290.  
  291.  
  292.  
  293. /*----------------------------------------------------------------------------
  294.     Personal
  295.  
  296.     Handles the personal info preferences dialog.
  297.     
  298.     Entry:    prefs = pointer to new prefs.
  299.             dlg = pointer to dialog.
  300.             item = item number hit.
  301. ----------------------------------------------------------------------------*/
  302.  
  303. static void Personal (TPrefRec *prefs, DialogPtr dlg, short item)
  304. {
  305.     switch (item) {
  306.     
  307.         case kInit:
  308.         
  309.             DlgSetCString(dlg, kFullName, prefs->fullName);
  310.             SetItemMaxLength(dlg, kFullName, 255);
  311.             DlgSetCString(dlg, kOrganization, prefs->organization);
  312.             SetItemMaxLength(dlg, kOrganization, 255);
  313.             DlgSetCString(dlg, kMailAddress, prefs->address);
  314.             SetItemMaxLength(dlg, kMailAddress, 255);
  315.             if (*prefs->fullName == 0) {
  316.                 SelIText(dlg, kFullName, 0, 0);
  317.             } else if (*prefs->organization == 0) {
  318.                 SelIText(dlg, kOrganization, 0, 0);
  319.             } else if (*prefs->address == 0) {
  320.                 SelIText(dlg, kMailAddress, 0, 0);
  321.             } else {
  322.                 SelIText(dlg, kFullName, 0, 0x7fff);
  323.             }
  324.             break;
  325.             
  326.         case kTerm:
  327.             
  328.             DlgGetCString(dlg, kFullName, prefs->fullName);
  329.             DlgGetCString(dlg, kOrganization, prefs->organization);
  330.             break;
  331.             
  332.         case kMailAddress:
  333.         
  334.             DlgGetCString(dlg, kMailAddress, prefs->address);
  335.             DlgEnableItem(dlg, ok, *prefs->address != 0);
  336.             DlgEnableItem(dlg, kTopicPopup, *prefs->address != 0);
  337.             
  338.     }
  339. }
  340.  
  341.  
  342.  
  343. /*----------------------------------------------------------------------------
  344.     DrawSigStaticText
  345.  
  346.     This user item procedure draws the static text item in the signature dialog. 
  347.     We need this because the dialog's font has been changed for editing the
  348.     signature.
  349.     
  350.     Entry:    dlg = pointer to dialog.
  351.             item = item number.
  352. ----------------------------------------------------------------------------*/
  353.  
  354. static pascal void DrawSigStaticText (DialogPtr dlg, short item)
  355. {
  356.     short itemType;
  357.     Handle itemHandle;
  358.     Rect box;
  359.     short oldFontNum, oldFontSize;
  360.     
  361.     GetDItem(dlg, item, &itemType, &itemHandle, &box);
  362.     oldFontNum = dlg->txFont;
  363.     oldFontSize = dlg->txSize;
  364.     TextFont(0);
  365.     TextSize(12);
  366.     TextBox(gStaticText+1, *gStaticText, &box, teJustLeft);
  367.     TextFont(oldFontNum);
  368.     TextSize(oldFontSize);
  369. }
  370.  
  371.  
  372.  
  373. /*----------------------------------------------------------------------------
  374.     Signature
  375.  
  376.     Handles the signature preferences dialog.
  377.     
  378.     Entry:    prefs = pointer to new prefs.
  379.             dlg = pointer to dialog.
  380.             item = item number hit.
  381. ----------------------------------------------------------------------------*/
  382.  
  383. static void Signature (TPrefRec *prefs, DialogPtr dlg, short item)
  384. {
  385.     short fontNum, fontSize;
  386.     short itemType;
  387.     Rect box;
  388.     Handle itemHandle;
  389.     TEHandle textH;
  390.     FontInfo fontInfo;
  391.     short itemSize;
  392.  
  393.     switch (item) {
  394.     
  395.         case kInit:
  396.         
  397.             DlgSetCheck(dlg, kAddSigSeparator, prefs->addSigSeparatorLine);
  398.         
  399.             /* Stuff the signature (maybe longer than 255) into the item */
  400.             
  401.             GetDItem(dlg, kSignature, &itemType, &itemHandle, &box);
  402.             PtrToXHand(prefs->signature, itemHandle, strlen(prefs->signature));
  403.             SelIText(dlg, kSignature, 0, 0x7fff);
  404.             SetItemReturnIsLegal(dlg, kSignature, true);
  405.             SetItemMaxLength(dlg, kSignature, 4095);
  406.     
  407.             /* Set the dialog's text edit area to use a different font */
  408.             
  409.             SetPort(dlg);
  410.             GetFNum(prefs->textFont, &fontNum);
  411.             fontSize = prefs->textSize;
  412.             textH = ((DialogPeek)dlg)->textH;
  413.             (**textH).txFont = fontNum;        /* Set it for TextEdit */
  414.             (**textH).txSize = fontSize;
  415.             TextFont(fontNum);                /* And for QuickDraw */
  416.             TextSize(fontSize);
  417.             GetFontInfo(&fontInfo);            /* Adjust the TE line heights */
  418.             (**textH).lineHeight = fontInfo.ascent+fontInfo.descent+fontInfo.leading;
  419.             (**textH).fontAscent = fontInfo.ascent;
  420.             TECalText(textH);
  421.     
  422.             /* Change the static text into a userItem so it can use the system font */
  423.             
  424.             GetDItem(dlg, kSigStaticText, &itemType, &itemHandle, &box);
  425.             GetIText(itemHandle, gStaticText);
  426.             SetDItem(dlg, kSigStaticText, userItem, (Handle)DrawSigStaticText, &box);
  427.             break;
  428.             
  429.         case kTerm:
  430.             
  431.             prefs->addSigSeparatorLine = DlgGetCheck(dlg, kAddSigSeparator);
  432.             GetDItem(dlg, kSignature, &itemType, &itemHandle, &box);
  433.             itemSize = GetHandleSize(itemHandle);
  434.             BlockMove(*itemHandle, prefs->signature, itemSize);
  435.             prefs->signature[itemSize] = 0;
  436.     
  437.             /* Reset the dialog's text edit area to Chicago 12 */
  438.             
  439.             SetPort(dlg);
  440.             fontNum = 0;
  441.             fontSize = 12;
  442.             textH = ((DialogPeek)dlg)->textH;
  443.             (**textH).txFont = fontNum;        /* Set it for TextEdit */
  444.             (**textH).txSize = fontSize;
  445.             TextFont(fontNum);                /* And for QuickDraw */
  446.             TextSize(fontSize);
  447.             GetFontInfo(&fontInfo);            /* Adjust the TE line heights */
  448.             (**textH).lineHeight = fontInfo.ascent+fontInfo.descent+fontInfo.leading;
  449.             (**textH).fontAscent = fontInfo.ascent;
  450.             TECalText(textH);
  451.             break;
  452.             
  453.         case kAddSigSeparator:
  454.         
  455.             DlgToggleCheck(dlg, kAddSigSeparator);
  456.             break;
  457.             
  458.     }
  459. }
  460.  
  461.  
  462.  
  463. /*----------------------------------------------------------------------------
  464.     Remote
  465.  
  466.     Handles the remote host info preferences dialog.
  467.     
  468.     Entry:    prefs = pointer to new prefs.
  469.             dlg = pointer to dialog.
  470.             item = item number hit.
  471. ----------------------------------------------------------------------------*/
  472.  
  473. static void Remote (TPrefRec *prefs, DialogPtr dlg, short item)
  474. {
  475.     CStr255 tempStr;
  476.     short len;
  477.  
  478.     switch (item) {
  479.     
  480.         case kInit:
  481.         
  482.             DlgSetCString(dlg, kRemoteHost, prefs->host);
  483.             SetItemMaxLength(dlg, kRemoteHost, 255);
  484.             DlgSetCString(dlg, kRemoteLogin, prefs->name);
  485.             SetItemMaxLength(dlg, kRemoteLogin, 255);
  486.             len = strlen(prefs->remotePassword);
  487.             memset(tempStr, '•', len);
  488.             tempStr[len] = 0;
  489.             DlgSetCString(dlg, kRemotePassword, tempStr);
  490.             SetItemPassword(dlg, kRemotePassword, prefs->remotePassword);
  491.             SetItemMaxLength(dlg, kRemotePassword, 31);
  492.             DlgSetCString(dlg, kRemotePath, prefs->remotePath);
  493.             SetItemMaxLength(dlg, kRemotePath, 31);
  494.             DlgSetCheck(dlg, kAutoGetPut, prefs->autoFetchnewsrc);
  495.             DlgSetCheck(dlg, kSavePassword, prefs->savePassword);
  496.             if (*prefs->host == 0) {
  497.                 SelIText(dlg, kRemoteHost, 0, 0);
  498.             } else if (*prefs->name == 0) {
  499.                 SelIText(dlg, kRemoteLogin, 0, 0);
  500.             } else if (*prefs->remotePassword == 0) {
  501.                 SelIText(dlg, kRemotePassword, 0, 0);
  502.             } else if (*prefs->remotePath == 0) {
  503.                 SelIText(dlg, kRemotePath, 0, 0);
  504.             } else {
  505.                 SelIText(dlg, kRemoteHost, 0, 0x7fff);
  506.             }
  507.             break;
  508.             
  509.         case kTerm:
  510.             
  511.             DlgGetCString(dlg, kRemoteHost, prefs->host);
  512.             DlgGetCString(dlg, kRemoteLogin, prefs->name);
  513.             DlgGetCString(dlg, kRemotePath, prefs->remotePath);
  514.             prefs->autoFetchnewsrc = DlgGetCheck(dlg, kAutoGetPut);
  515.             prefs->savePassword = DlgGetCheck(dlg, kSavePassword);
  516.             break;
  517.         
  518.         case kSavePassword:
  519.         case kAutoGetPut:
  520.         
  521.             DlgToggleCheck(dlg, item);
  522.             break;
  523.             
  524.     }
  525. }
  526.  
  527.  
  528.  
  529. /*----------------------------------------------------------------------------
  530.     DrawFontSample
  531.     
  532.     A user item procedure to draw the font samples.
  533.     
  534.     Entry:    dlg = pointer to dialog.
  535.             item = item number.
  536. ----------------------------------------------------------------------------*/
  537.  
  538. static pascal void DrawFontSample (DialogPtr dlg, short item)
  539. {
  540.     short itemType;
  541.     Rect box;
  542.     Handle itemHandle;
  543.     StringPtr text;
  544.     short fontID, fontSize, saveFont, saveSize;
  545.     GrafPtr curPort;
  546.  
  547.     DlgGrayBorderItem(dlg, item);
  548.     GetDItem(dlg, item, &itemType, &itemHandle, &box);
  549.     if (item == kListSample) {
  550.         text = "\pThis is the font and size in which NewsWatcher group and subject lists are displayed.";
  551.         fontID = gListFontID;
  552.         fontSize = gListFontSize;
  553.     } else {
  554.         text = "\pThis is the font and size in which NewsWatcher article and message windows are displayed.";
  555.         fontID = gTextFontID;
  556.         fontSize = gTextFontSize;
  557.     }
  558.     GetPort(&curPort);
  559.     saveFont = curPort->txFont;
  560.     saveSize = curPort->txSize;
  561.     TextFont(fontID);
  562.     TextSize(fontSize);
  563.     InsetRect(&box, 2, 2);
  564.     TextBox(text + 1, *text, &box, teFlushDefault);
  565.     TextFont(saveFont);
  566.     TextSize(saveSize);
  567. }
  568.  
  569.  
  570.  
  571. /*----------------------------------------------------------------------------
  572.     RedrawSample
  573.  
  574.     Force one of the sample text items to be redrawn.
  575.     
  576.     Entry:    dlg = pointer to dialog.
  577.             item = item number.
  578. ----------------------------------------------------------------------------*/
  579.  
  580. static void RedrawSample (DialogPtr dlg, short item)
  581. {
  582.     short itemType;
  583.     Handle itemHandle;
  584.     Rect box;
  585.     
  586.     SetPort(dlg);
  587.     GetDItem(dlg, item, &itemType, &itemHandle, &box);
  588.     InsetRect(&box, 2, 2);
  589.     EraseRect(&box);
  590.     InvalRect(&box);
  591. }
  592.  
  593.  
  594.  
  595. /*----------------------------------------------------------------------------
  596.     SetNewFont
  597.  
  598.     Set a new font in the font/size dialog.
  599.     
  600.     Entry:    dlg = pointer to dialog.
  601.             listFont = true if list font, false if text font.
  602.             fontNum = new font number.
  603. ----------------------------------------------------------------------------*/
  604.  
  605. static void SetNewFont (DialogPtr dlg, Boolean listFont, short fontNum)
  606. {
  607.     short numItems, itemType, i;
  608.     Rect box;
  609.     Handle itemHandle;
  610.     Str255 itemStr, fontName;
  611.     ControlHandle ctl;
  612.     long size;
  613.  
  614.     /* Select the right font in the font popup menu. */
  615.     
  616.     ctl = DlgGetControl(dlg, listFont ? kListFontPopup : kTextFontPopup);
  617.     GetFontName(fontNum, fontName);
  618.     SetPopupValue(ctl, fontName, false);
  619.     
  620.     /* Adjust the size popup so the nice sizes are outlined. */
  621.  
  622.     ctl = DlgGetControl(dlg, listFont ? kListSizePopup : kTextSizePopup);
  623.     numItems = GetCtlMax(ctl);
  624.     for (i = 1; i <= numItems; i++) {
  625.         GetPopupPString(ctl, i, itemStr);
  626.         StringToNum(itemStr, &size);
  627.         if (RealFont(fontNum, (short)size)) {
  628.             SetPopupItemStyle(ctl, i, outline);
  629.         } else {
  630.             SetPopupItemStyle(ctl, i, 0);
  631.         }
  632.     }
  633.  
  634.     /* Force the sample text to be redrawn */
  635.     
  636.     RedrawSample(dlg, listFont ? kListSample : kTextSample);
  637. }
  638.  
  639.  
  640.  
  641. /*----------------------------------------------------------------------------
  642.     FontIDFromPopup
  643.  
  644.     Get the font ID corresponding the currently selected font in a popup menu.
  645.     
  646.     Entry:    dlg = pointer to dialog.
  647.             item = item number of popup menu.
  648. ----------------------------------------------------------------------------*/
  649.  
  650. static short FontIDFromPopup (DialogPtr dlg, short item)
  651. {
  652.     ControlHandle ctl;
  653.     short fontNum;
  654.     Str255 fontName;
  655.  
  656.     ctl = DlgGetControl(dlg, item);
  657.     GetPopupPString(ctl, kCurrentPopupItem, fontName);
  658.     GetFNum(fontName, &fontNum);
  659.     return fontNum;
  660. }
  661.  
  662.  
  663.  
  664. /*----------------------------------------------------------------------------
  665.     Font
  666.  
  667.     Handles the font and size preferences dialog.
  668.     
  669.     Entry:    prefs = pointer to new prefs.
  670.             dlg = pointer to dialog.
  671.             item = item number hit.
  672. ----------------------------------------------------------------------------*/
  673.  
  674. static void Font (TPrefRec *prefs, DialogPtr dlg, short item)
  675. {
  676.     Str255 tempStr;
  677.     long num;
  678.  
  679.     switch (item) {
  680.     
  681.         case kInit:
  682.         
  683.             GetFNum(prefs->listFont, &gListFontID);
  684.             gListFontSize = prefs->listSize;
  685.             SetNewFont(dlg, true, gListFontID);
  686.             DlgSetNumber(dlg, kListSizeBox, gListFontSize);
  687.             SetItemNumeric(dlg, kListSizeBox, true);
  688.             SetItemMaxLength(dlg, kListSizeBox, 2);
  689.             SelIText(dlg, kListSizeBox, 0, 0x7fff);
  690.             SetItemPopupTypeinItem(dlg, kListSizePopup, kListSizeBox);
  691.             
  692.             GetFNum(prefs->textFont, &gTextFontID);
  693.             gTextFontSize = prefs->textSize;
  694.             SetNewFont(dlg, false, gTextFontID);
  695.             DlgSetNumber(dlg, kTextSizeBox, gTextFontSize);
  696.             SetItemNumeric(dlg, kTextSizeBox, true);
  697.             SetItemMaxLength(dlg, kTextSizeBox, 2);
  698.             SetItemPopupTypeinItem(dlg, kTextSizePopup, kTextSizeBox);
  699.             
  700.               DlgSetUserItem(dlg, kListSample, DrawFontSample);
  701.               DlgSetUserItem(dlg, kTextSample, DrawFontSample);
  702.               DlgSetUserItem(dlg, kListVertLine, DlgGrayBorderItem);
  703.             break;
  704.             
  705.         case kTerm:
  706.             
  707.               GetFontName(gListFontID, prefs->listFont);
  708.               GetFontName(gTextFontID, prefs->textFont);
  709.               prefs->listSize = gListFontSize;
  710.               prefs->textSize = gTextFontSize;
  711.             break;
  712.             
  713.         case kListFontPopup:
  714.         
  715.               gListFontID = FontIDFromPopup(dlg, item);
  716.               SetNewFont(dlg, true, gListFontID);
  717.             break;
  718.             
  719.         case kTextFontPopup:
  720.         
  721.               gTextFontID = FontIDFromPopup(dlg, item);
  722.               SetNewFont(dlg, false, gTextFontID);
  723.             break;            
  724.           
  725.         case kListSizePopup:
  726.         
  727.               GetPopupPString(DlgGetControl(dlg, item), kCurrentPopupItem, tempStr);
  728.               DlgSetPString(dlg, kListSizeBox, tempStr);
  729.               SelIText(dlg, kListSizeBox, 0, 0x7fff);
  730.             /* Fall through! */
  731.             
  732.         case kListSizeBox:
  733.         
  734.               DlgGetPString(dlg, kListSizeBox, tempStr);
  735.               StringToNum(tempStr, &num);
  736.               if (num != 0 && num != gListFontSize) {
  737.                   gListFontSize = num;
  738.                   RedrawSample(dlg, kListSample);
  739.               }
  740.             break;
  741.           
  742.         case kTextSizePopup:
  743.         
  744.               GetPopupPString(DlgGetControl(dlg, item), kCurrentPopupItem, tempStr);
  745.               DlgSetPString(dlg, kTextSizeBox, tempStr);
  746.               SelIText(dlg, kListSizeBox, 0, 0x7fff);
  747.             /* Fall through! */
  748.             
  749.         case kTextSizeBox:
  750.         
  751.               DlgGetPString(dlg, kTextSizeBox, tempStr);
  752.               StringToNum(tempStr, &num);
  753.               if (num != 0 && num != gTextFontSize) {
  754.                   gTextFontSize = num;
  755.                   RedrawSample(dlg, kTextSample);
  756.               }
  757.             break;
  758.             
  759.     }
  760. }
  761.  
  762.  
  763.  
  764. /*----------------------------------------------------------------------------
  765.     Saved
  766.  
  767.     Handles the saved text file preferences dialog.
  768.     
  769.     Entry:    prefs = pointer to new prefs.
  770.             dlg = pointer to dialog.
  771.             item = item number hit.
  772. ----------------------------------------------------------------------------*/
  773.  
  774. static void Saved (TPrefRec *prefs, DialogPtr dlg, short item)
  775. {
  776.     StandardFileReply reply;
  777.     FInfo fInfo;
  778.     long dirID;
  779.     Str31 name;
  780.     OSErr err;
  781.     CInfoPBRec cpb;
  782.     HParamBlockRec pb;
  783.  
  784.     switch (item) {
  785.     
  786.         case kInit:
  787.  
  788.               DlgSetUserItem(dlg, kAppBorder, DlgGrayBorderItem);
  789.             DlgSetPString(dlg, kAppName, prefs->textCreatorName);
  790.             DlgSetCheck(dlg, kDirCheckBox, prefs->textDefaultDir);
  791.               DlgSetUserItem(dlg, kDirBorder, DlgGrayBorderItem);            
  792.             err = VolNameToVRefNum (prefs->textVolName, &cpb.dirInfo.ioVRefNum);
  793.               if (err == noErr) {
  794.                 cpb.dirInfo.ioNamePtr = name;
  795.                 cpb.dirInfo.ioFDirIndex = -1;
  796.                 cpb.dirInfo.ioDrDirID = prefs->textDirID;
  797.                 err = PBGetCatInfo(&cpb, false);
  798.             }
  799.             if (err != noErr) *name = 0;
  800.             DlgSetPString(dlg, kDirName, name);
  801.             DlgEnableItem(dlg, kDirButton, prefs->textDefaultDir);
  802.                 
  803.             break;
  804.             
  805.         case kTerm:
  806.         
  807.             break;
  808.             
  809.         case kAppButton:
  810.         
  811.             MyStandardGetFile(nil, 1, (OSType*)"APPL", &reply);
  812.             if (!reply.sfGood) break;
  813.             FSpGetFInfo(&reply.sfFile, &fInfo);
  814.             prefs->textCreator = fInfo.fdCreator;
  815.             pstrcpy(prefs->textCreatorName, reply.sfFile.name);
  816.             DlgSetPString(dlg, kAppName, prefs->textCreatorName);
  817.             break;
  818.             
  819.         case kDirCheckBox:
  820.         
  821.             DlgToggleCheck(dlg, item);
  822.             prefs->textDefaultDir = DlgGetCheck(dlg, item);
  823.             DlgEnableItem(dlg, kDirButton, prefs->textDefaultDir);
  824.             break;
  825.             
  826.         case kDirButton:
  827.         
  828.             MyStandardGetDirectory(&reply, &dirID);
  829.             if (!reply.sfGood) break;
  830.             prefs->textDirID = dirID;
  831.             pb.volumeParam.ioNamePtr = prefs->textVolName;
  832.             pb.volumeParam.ioVRefNum = reply.sfFile.vRefNum;
  833.             pb.volumeParam.ioVolIndex = 0;
  834.             PBHGetVInfo(&pb, false);
  835.             DlgSetPString(dlg, kDirName, reply.sfFile.name);
  836.             break;
  837.             
  838.     }
  839. }
  840.  
  841.  
  842.  
  843. /*----------------------------------------------------------------------------
  844.     Auth
  845.  
  846.     Handles the authorization preferences dialog.
  847.     
  848.     Entry:    prefs = pointer to new prefs.
  849.             dlg = pointer to dialog.
  850.             item = item number hit.
  851. ----------------------------------------------------------------------------*/
  852.  
  853. static void Auth (TPrefRec *prefs, DialogPtr dlg, short item)
  854. {
  855.     switch (item) {
  856.     
  857.         case kInit:
  858.         
  859.             break;
  860.             
  861.         case kTerm:
  862.             
  863.             break;
  864.             
  865.     }
  866. }
  867.  
  868.  
  869.  
  870. /*----------------------------------------------------------------------------
  871.     DoPrefsDialog
  872.  
  873.     Presents the Preferences dialog.
  874. ----------------------------------------------------------------------------*/
  875.  
  876.  
  877. void DoPrefsDialog (void)
  878. {
  879.     typedef void (*prefsFuncPtr) (TPrefRec *prefs, DialogPtr dlg, short item);
  880.     
  881.     static prefsFuncPtr prefsFuncPtrs[] = {
  882.         GeneralOptions,
  883.         Server,
  884.         ServerOptions,
  885.         Personal,
  886.         Signature,
  887.         Remote,
  888.         Font,
  889.         Saved,
  890.         Auth,
  891.     };
  892.  
  893.     static short curTopic = kGeneralOptions;
  894.     
  895.     short newTopic;
  896.     prefsFuncPtr theFunc;
  897.     TPrefRec *prefs;
  898.     DialogPtr dlg;
  899.     short item;
  900.     CStr255 msg;
  901.     Boolean listFontChanged, textFontChanged;
  902.     Handle theDITL;
  903.     
  904.     prefs = (TPrefRec*)MyNewPtr(sizeof(TPrefRec));
  905.     *prefs = gPrefs;
  906.     
  907.     dlg = MyGetNewDialog(kPrefsDlg);
  908.     theDITL = GetResource('DITL', kPrefsDlg + curTopic);
  909.     MyAppendDITL(dlg, theDITL, overlayDITL);
  910.     ReleaseResource(theDITL);
  911.     DlgSetCtlValue(dlg, kTopicPopup, curTopic);
  912.     theFunc = prefsFuncPtrs[curTopic - 1];
  913.     (*theFunc)(prefs, dlg, kInit);
  914.     ShowWindow(dlg);
  915.     
  916.     while (true) {
  917.         MyModalDialog(DialogFilter, &item, true, curTopic != kSignature);
  918.         if (item == ok || item == cancel) {
  919.             (*theFunc)(prefs, dlg, kTerm);
  920.             break;
  921.         } else if (item == kTopicPopup) {
  922.             newTopic = DlgGetCtlValue(dlg, kTopicPopup);
  923.             if (newTopic != curTopic) {
  924.                 (*theFunc)(prefs, dlg, kTerm);
  925.                 curTopic = newTopic;
  926.                 MyShortenDITL(dlg, CountDITL(dlg) - 3);
  927.                 theDITL = GetResource('DITL', kPrefsDlg + curTopic);
  928.                 MyAppendDITL(dlg, theDITL, overlayDITL);
  929.                 ReleaseResource(theDITL);
  930.                 theFunc = prefsFuncPtrs[curTopic - 1];
  931.                 (*theFunc)(prefs, dlg, kInit);
  932.             }
  933.         } else {
  934.             (*theFunc)(prefs, dlg, item);
  935.         }
  936.     }
  937.     
  938.     MyDisposDialog(dlg);
  939.     
  940.     if (item == ok) {
  941.         if (prefs->logActionsToFile && !gPrefs.logActionsToFile) {
  942.             OpenLogFile();
  943.         } else if (!prefs->logActionsToFile && gPrefs.logActionsToFile) {
  944.             CloseLogFile();
  945.         }
  946.         if (!EqualString(prefs->newsServerName, gPrefs.newsServerName, false, true)) {
  947.             strcpy(msg, "You must quit and restart the program ");
  948.             strcat(msg, "for the news server change to take effect.");
  949.             ErrorMessage(msg);
  950.         }
  951.         listFontChanged = prefs->listSize != gPrefs.listSize ||
  952.             !EqualString(prefs->listFont, gPrefs.listFont, false, true);
  953.         textFontChanged = prefs->textSize != gPrefs.textSize ||
  954.             !EqualString(prefs->textFont, gPrefs.textFont, false, true);
  955.         gPrefs = *prefs;
  956.         if (listFontChanged) {
  957.             gPrefs.maxGroupNameWidth = 0;
  958.             FontWasChanged(true);
  959.         }
  960.         if (textFontChanged) {
  961.             FontWasChanged(false);
  962.         }
  963.     }
  964.     MyDisposPtr((Ptr)prefs);
  965. }
  966.